package ufpi.br.dao;

import br.ufpi.domain.Resposta;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import br.ufpi.domain.Usuario;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.LogicalExpression;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;

public class UsuarioDao extends DAOImpl<Usuario> {

    public UsuarioDao() {
        super(Usuario.class);

    }

    @Override
    protected Long getIdObj(Usuario obj) {
        return obj.getId();
    }

    @Override
    protected void setIdObj(Usuario obj, Long id) {
        obj.setId(id);

    }

    public Usuario buscaMatricula(String matricula) {
        Criteria c = getSession().createCriteria(getPersistentClass()).add(
                Restrictions.eq("matricula", matricula));
        return (Usuario) c.uniqueResult();

    }

    public boolean alterarSenha(String matricula, String senhaAntiga,
            String senhaNova) {
        Usuario usuario = this.buscaMatricula(matricula);
        if (usuario != null) {
            if (usuario.getSenha().equals(senhaAntiga)) {
                System.out.println("Diferente de null");
                usuario.setSenha(senhaNova);
                this.update(usuario);

                return true;
            }
        }
        return false;
    }

    public Usuario validateLogin(String matricula, String senha) {
        Usuario usuario = this.buscaMatricula(matricula);
        if (usuario != null) {
            if (usuario.getSenha().equals(senha)) {
                return usuario;
            } else {
                return null;
            }
        }
        return usuario;
    }

    /*
     * Busca todos os usuarios que estao com o cadastro ACEITO, não
     * pendente
     */
    public Collection<Usuario> listUsuariosPendentes() {
        Query q = getSession().createQuery("from Usuario where status = :status");
        // Status 0 = Usuario ainda nao foi analisada
        // Status 1 = Usuario correta OK
        // Status 2 = Usuario parcialmente correta

        q.setParameter("status", 0);
        return q.list();
    }

    public Collection<Usuario> listUsuariosAceitos() {
        Query q = getSession().createQuery("from Usuario where status = :status");
        // Status 0 = Usuario ainda nao foi analisada
        // Status 1 = Usuario correta OK
        // Status 2 = Usuario parcialmente correta
        q.setParameter("status", 1);
        return q.list();
    }
/**
 * Retornar todos os pontos de um usuario.
 * @param matricula
 * @param date
 * @param finalDate
 * @return
 */
    public Double getMeusPontos(String matricula, Date date, Date finalDate) {
        UsuarioDao usuarioDao = new UsuarioDao();
        Usuario usuario = usuarioDao.buscaMatricula(matricula);
        System.out.println(usuario.getNomeCompleto());
        Criteria pontuacaoTotal = getSession().createCriteria(Resposta.class);
        Criterion not = Restrictions.not(Restrictions.eq("pontuacao", 0.0));
        LogicalExpression expression = Restrictions.and(not, Restrictions.eq("usuario", usuario));
        if (date != null) {
            if (finalDate != null) {
                expression = Restrictions.and(expression, Restrictions.between("dataEnvio", date, finalDate));
            } else {
                expression = Restrictions.and(expression, Restrictions.between("dataEnvio", date, new Date()));
            }
        } else {
            if (finalDate != null) {
                Date aux = new Date();
                Calendar calendar = Calendar.getInstance();
                calendar.set(2000, 0, 0);
                aux = calendar.getTime();
                expression = Restrictions.and(expression, Restrictions.between("dataEnvio", aux, finalDate));
            }
        }
        pontuacaoTotal.add(expression);
        return (Double) pontuacaoTotal.setProjection(Projections.sum("pontuacao")).uniqueResult();
    }
    
    private Collection<Usuario> listarUsuariosComPontuacao(Date data, Date data2) {
        UsuarioDao dao = new UsuarioDao();
        
        ArrayList<Usuario> users = (ArrayList) dao.listAll();
        Iterator<Usuario> it = users.iterator();
        RespostaDao rDao = new RespostaDao();
        while(it.hasNext()) {
            Usuario u = it.next();
            if(!u.isAdmin()) {
                Double soma=this.getMeusPontos(u.getMatricula(),data, data2);
                System.out.println(soma);
                if(soma==null)
                    u.setPontosExtra(0);
                else
                    u.setPontosExtra(soma);
               dao.update(u);
            }
        }
        return users;
    }
    
    public Collection<Usuario> listarUserComPontuacao(Date date, Date date2) {
        listarUsuariosComPontuacao(date, date2);
        Criteria c = getSession().createCriteria(Usuario.class);
        c.add(Restrictions.eq("status", 1));
        //c.add(Restrictions.eq("isAdmin", false));
        c.addOrder(Order.desc("pontosExtra"));
        return c.list();
    }
    
    public Collection<Usuario> listarUserComPontuacaoLimite(int limite,Date date, Date date2) {
        listarUsuariosComPontuacao(date, date2);
        Criteria c = getSession().createCriteria(Usuario.class);
        c.add(Restrictions.eq("status", 1));
        c.add(Restrictions.eq("isAdmin", false));
        c.addOrder(Order.desc("pontosExtra"));
         c.setMaxResults(limite);
        
        return c.list();
    }
     public Collection<Usuario> listarAdmin() {
        Criteria c = getSession().createCriteria(Usuario.class);
        c.add(Restrictions.eq("isAdmin", true));
        return c.list();
    }
    
}
